package tools

import (
	"context"
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"go-chain-data/global"
	"go-chain-data/models"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
)

func SendCallBack(body *models.CallBackBody, sign string, nonce string, timestamp string, urls string, insertedId primitive.ObjectID) error {
	//解析body
	bodyJson, err := json.Marshal(body)
	if err != nil {
		return err
	}
	sendBody := url.Values{
		"timestamp": {timestamp},
		"nonce":     {nonce},
		"sign":      {sign},
		"body":      {string(bodyJson)},
	}
	err, respBody, statusCode := SendPost(sendBody, urls)
	if err != nil {
		return err
	}
	update := bson.D{{"callBackResult", respBody}}
	if statusCode == 200 {
		update = append(update, bson.E{Key: "verify", Value: 1})
	}
	_, err = global.DBEngine.Database(global.DbConfig.DbName).Collection("collection_callback").UpdateOne(context.Background(), bson.M{"_id": insertedId}, bson.M{"$set": update})
	if err != nil {
		log.Println("更新collection_callback失败:", err)
		return err
	}
	return nil
}

func GetSign(body *models.CallBackBody, key string, nonce string, timestamp string) (string, error) {
	bodyJson, err := json.Marshal(body)
	if err != nil {
		return "", err
	}
	data := []byte(string(bodyJson) + key + nonce + timestamp)
	hash := md5.Sum(data)
	sign := hex.EncodeToString(hash[:])
	return sign, nil
}

func SendPost(data url.Values, urls string) (error, string, int) {

	resp, err := http.PostForm(urls, data)
	if err != nil {
		return err, "", 0
	}
	defer resp.Body.Close()

	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err, "", 0
	}
	return nil, string(respBody), resp.StatusCode
}

func SendDappCallBack(body models.WatchAddressInfo, urls string, insertedId primitive.ObjectID) error {
	//解析body
	bodyJson, err := json.Marshal(body)
	if err != nil {
		return err
	}
	sendBody := url.Values{
		"body": {string(bodyJson)},
	}

	resp, err := http.PostForm(urls, sendBody)
	if err != nil || resp.StatusCode != http.StatusOK {
		return err
	}
	defer resp.Body.Close()

	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		// 处理读取错误
		log.Println("Error reading response body:", err)
		return err
	}
	body.Verify = 1
	body.CallBackResult = string(respBody)
	_, err = global.DBEngine.Database(global.DbConfig.DbName).Collection("watch_address_info").UpdateOne(context.Background(), bson.M{"id": insertedId}, bson.M{"$set": body})
	if err != nil {
		log.Println("更新watch—address-info失败:", err)
		return err
	}

	return nil
}
